from datetime import datetime, time
from time import sleep
import random

from PySide2.QtCore import Qt
from PySide2.QtGui import QPainter
from PySide2.QtWidgets import QApplication, QMessageBox, QWidget, QTableWidgetItem, QVBoxLayout

from PySide2.QtCharts import QtCharts
from PySide2.QtGui import QPen, QColor

from pandas import DataFrame

from models import Product, Sensor

from ui_main_frame import Ui_Form
from public import PublicData
from ui_thread import Th_sensor_search, Th_get_sonsor_data, Th_analysis_data

from db.tb_tread import change_product, change_sensor_set_list
from ui_func import show_sensor, setup_tb_sensor, send_sensor_data_to_queue, check_first_record, data_list_to_series, \
    show_bend_chart


class MyWindow(QWidget, Ui_Form):
    def __init__(self):
        super().__init__()
        self.range_number = 100

        self.canvas = None
        self.ui = Ui_Form()
        self.ui.setupUi(self)
        self.th_search_bar = None
        self.th_find_sensor = None
        self.searching = False
        self.threads = {}

        self.public_data = PublicData()
        self.ui.pro_search.setVisible(False)
        self.bend_value_count = 0  # 计算的弯曲角度值的数量
        # region 折线图的相关设置
        self.axis_x = QtCharts.QValueAxis()  # 定义X轴, ACC和角度共用

        # 角度曲线
        self.agree_chart = QtCharts.QChart()
        self.agree_chart.setTitle("弯曲角度过程曲线")
        self.agree_chart_view = QtCharts.QChartView(self.agree_chart)
        self.agree_chart_view.setRenderHint(QPainter.Antialiasing)

        # self.ser_bend_chart_A = QtCharts.QLineSeries()
        # self.ser_bend_chart_B = QtCharts.QLineSeries()
        self.ser_bend_chart_All = QtCharts.QLineSeries()
        self.ser_bend_chart_Alarm = QtCharts.QLineSeries()

        self.bend_axis_y = QtCharts.QValueAxis()  # 定义Y轴

        # 加速度曲线
        self.acc_chart = QtCharts.QChart()
        self.acc_chart.setTitle("弯曲的加速度")
        self.acc_chart_view = QtCharts.QChartView(self.acc_chart)

        self.ser_acc_chart_B = QtCharts.QLineSeries()
        self.ser_acc_chart_A = QtCharts.QLineSeries()

        self.acc_axis_y = QtCharts.QValueAxis()  # 定义Y轴

        vbox = QVBoxLayout(self.ui.wdg_qchart)
        vbox.addWidget(self.agree_chart_view)
        vbox.addWidget(self.acc_chart_view)

        # endregion

        # 按钮事件绑定
        self.bind()

        setup_tb_sensor(self.ui.tb_sensor)
        # test data
        self.ui.txt_label.setText("123450")
        self.ui.txt_product.setText("LF400101")
        self.ui.txt_project_code.setText("LF")

        self.init_chart()

    # 添加曲线图控件
    def init_chart(self):
        # x轴
        self.axis_x.setRange(0, self.range_number)
        self.axis_x.setTitleText("数据序列")
        # axis_x.setTickCount(51)

        # y 轴
        axis_y = self.bend_axis_y  # 定义X轴
        alam_value = self.public_data.agree_max
        if alam_value < 1:
            alam_value = 90
            self.public_data.agree_max = alam_value
        axis_y.setRange(0, alam_value + 10)
        self.bend_axis_y.setTitleText("角度值:°")
        # self.bend_axis_y.setLabelFormat(".1f%")  # 数据的表达格式
        # axis_y.setTickCount(11)

        self.agree_chart.addAxis(self.axis_x, Qt.AlignBottom)
        self.agree_chart.addAxis(self.bend_axis_y, Qt.AlignLeft)

        self.agree_chart.addSeries(self.ser_bend_chart_Alarm)
        self.agree_chart.addSeries(self.ser_bend_chart_All)

        # 警戒值曲线

        color = QColor("red")
        pen = QPen(color)
        self.ser_bend_chart_Alarm.setPen(pen)

        self.ser_bend_chart_Alarm.setName("警戒线")
        self.ser_bend_chart_Alarm.attachAxis(self.axis_x)
        self.ser_bend_chart_Alarm.attachAxis(axis_y)

        self.ser_bend_chart_Alarm.append(1, 40)
        self.ser_bend_chart_Alarm.append(5, 40)
        self.ser_bend_chart_Alarm.append(self.range_number / 2, 40)
        self.ser_bend_chart_Alarm.append(self.range_number, 40)

        # 弯曲角度
        self.ser_bend_chart_All.setName("角度")
        self.ser_bend_chart_All.attachAxis(self.axis_x)
        self.ser_bend_chart_All.attachAxis(axis_y)
        self.ser_bend_chart_All.append(1, 20)
        self.ser_bend_chart_All.append(2, 23)
        self.bend_value_count = 2



        #

        #

        # 加速度值

        # self.acc_axis_y.setRange(0, 10)  # 设置刻度的范围
        # self.acc_axis_y.setTickCount(20)  # 设置刻度的数量
        # self.acc_chart.addAxis(self.acc_axis_y, Qt.AlignLeft)
        # self.acc_chart.addAxis(axis_x, Qt.AlignBottom)

        # self.ser_acc_chart_A.attachAxis(axis_x)
        # self.ser_acc_chart_A.attachAxis(self.acc_axis_y)
        # self.ser_acc_chart_B.attachAxis(axis_x)
        # self.ser_acc_chart_A.attachAxis(self.acc_axis_y)

    # region 按钮操作

    def bind(self):
        self.ui.btn_save_product.clicked.connect(self.save_product)
        self.ui.btn_save_senser_setting.clicked.connect(self.save_sensor_setting)

        self.ui.btn_search_sensor.clicked.connect(self.btn_search_sensor)
        self.ui.btn_start.clicked.connect(self.start_record)
        self.ui.btn_stop.clicked.connect(self.stop_record)
        self.ui.agree_max.valueChanged.connect(self.set_agree_max_value)

    # region 保存产品信息
    def save_product(self):
        product = self.get_product_data()  # 将GUI中的产品信息转为product对象
        if product and change_product(product):
            QMessageBox.information(self, "操作结果", "更新数据成功！")
        if self.public_data.sensor_dic:
            for sensor in self.public_data.sensor_dic.values():
                sensor.product_id = product.id

    def get_product_data(self):
        public_data = self.public_data
        product_label = self.ui.txt_label.text()

        if not product_label:
            QMessageBox.warning(self, "信息填写不全", "未填写产品编码")
            return None
        product_name = self.ui.txt_product.text()
        product_project = self.ui.txt_project_code.text()
        start_date = datetime.now().strftime("%Y-%m-%d")
        product = public_data.product
        if product:
            product.label = product_label
            product.name = product_name
            product.project = product_project
            product.start_date = start_date
        else:
            product = Product(0, product_label, product_name, product_project, start_date)
        self.public_data.product = product
        return product

    # endregion
    def set_agree_max_value(self):
        self.public_data.agree_max = float(self.ui.agree_max.text())

    # region 搜索传感器
    def set_progressBar(self, counter):
        self.ui.pro_search.setValue(counter)
        if counter >= 98:
            self.searching = False

    def get_sensor_code(self, data):
        """
            获取传感器数据，处理并显示传感器数据
            """
        # 判断是否是查询命令
        if self.searching:
            sensor_code = data[0]
            if sensor_code not in self.public_data.sensor_code_list:
                self.public_data.sensor_code_list.append(sensor_code)
                show_sensor(self.ui.tb_sensor)
        else:
            # 将数据传至数据队列
            send_sensor_data_to_queue(data)

    def btn_search_sensor(self):
        """启动传感器搜索功能，并显示数据"""
        self.ui.pro_search.setVisible(True)
        self.searching = True
        # 调用搜索传感器线程
        self.threads[1] = Th_sensor_search()
        self.threads[1].start()
        self.threads[1].signal_send.connect(self.set_progressBar)
        self.threads[2] = Th_get_sonsor_data()
        self.threads[2].start()
        self.threads[2].signal_send.connect(self.get_sensor_code)

        self.threads[3] = Th_analysis_data()
        self.threads[3].start()
        self.threads[3].signal_send.connect(self.tread_analysis_info)

        # self.th_tread_data()

    # endregion

    # region 保存传感器设置
    def save_sensor_setting(self):
        """保存传感器的设置"""
        if not self.public_data.sensor_code_list:
            QMessageBox.information(self, "操作结果", "请先搜索查询传感器！")
            return

        sensors = self.get_sensor_setting()
        if sensors:
            change_sensor_set_list(sensors)
            QMessageBox.information(self, "操作结果", "更新传感器设置成功！")

    def get_sensor_setting(self):
        product = self.public_data.product
        if not product or not product.id:
            QMessageBox.warning(self, "信息填写不全", "请先填写和保存产品信息")
            return None
        tb_senor = self.ui.tb_sensor
        sensor_dic = self.public_data.sensor_dic
        col_count = tb_senor.rowCount()
        tem1 = tb_senor.item(0, 0).text()
        if tem1 == "no_senor":
            return None
        for i in range(col_count):
            sensor_code = tb_senor.item(i, 0).text()
            location = tb_senor.cellWidget(i, 1).get_value()
            agree = tb_senor.cellWidget(i, 2).get_value()
            if sensor_code in sensor_dic.keys():
                sensor = sensor_dic[sensor_code]
                sensor.location = location
                sensor.agree = agree
                sensor.product_id = product.id
            else:
                sensor_dic[sensor_code] = Sensor(0, sensor_code, location, agree, product.id)
        return list(self.public_data.sensor_dic.values())

    # endregion

    # endregion

    # region 处理数据

    # endregion
    # 展示和存储数据
    def show_bend_data(self, sensor_data_dict):
        print("获取的角度信息是:", sensor_data_dict)
        sensor_dict = self.public_data.sensor_dic
        value_a = 0
        value_b = 0

        for sensor_code in sensor_data_dict.keys():
            sensor = sensor_dict[sensor_code]
            sensor_data = sensor_data_dict[sensor_code]

            if sensor.location == "A端":
                self.public_data.bend_data_dict["A"] = sensor_data[0]
                self.public_data.bend_data_dict["A_ACC"] = sensor_data[1]
                value_a = sensor_data[0]
            elif sensor.location == "B端":

                value_b = sensor_data[0]
                self.public_data.bend_data_dict["B"] = sensor_data[0]
                self.public_data.bend_data_dict["B_ACC"] = sensor_data[1]
        if value_a > 0 and value_b > 0:
            self.ui.lbb_degree.setText(str(value_a))
            self.ui.lba_degree.setText(str(value_b))
            bend_value = round(value_a + value_b, 2)
            self.public_data.bend_data_dict["T"] = bend_value
            self.ui.lbtotal_degree.setText(str(bend_value))
            self.add_bend_data_to_chart()

    def show_sensor_data(self, df_data: DataFrame):
        tb_sensor = self.ui.tb_sensor

        public_data = self.public_data
        sensor_code_list = public_data.sensor_code_list
        tb_col_name = ["sensor_code", "location", "agree", "angle_x", "angle_y", "angle_z", "acc_x", "acc_y", "acc_z",
                       "temp", "bat"]
        show_data_col = ["angle_x", "angle_y", "angle_z", "acc_x", "acc_y", "acc_z", "acc_x", "temp", "bat"]
        for sensor_code in sensor_code_list:
            row_index = sensor_code_list.index(sensor_code)
            for col_name in show_data_col:
                tb_sensor.setItem(row_index, tb_col_name.index(col_name),
                                  QTableWidgetItem(str(df_data.loc[sensor_code, col_name])))

    def set_record(self, if_record: bool):
        self.public_data.data_save_signal = if_record
        self.ui.btn_start.setEnabled(not if_record)
        self.ui.btn_stop.setEnabled(if_record)

    def stop_record(self):
        reply = QMessageBox.question(self, '确认', '请确认是否真的要停止数据记录', QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)

        if reply:
            self.set_record(False)
            self.threads[3].stop()

    def tread_analysis_info(self, info_dic):
        if info_dic:
            label = info_dic["label"]
            data = info_dic["data"]
            if label == "show_data":
                self.show_sensor_data(data)
            elif label == "msg":
                QMessageBox.warning(self, *data)
                self.set_record(False)
            elif label == "bend_value":
                self.show_bend_data(data)

    def start_record(self):
        # self.test_chart()
        if not self.public_data.sensor_dic or not self.public_data.product:
            QMessageBox.warning(self, "信息填写不全", "请设置传感器和产品信息并保存")
            self.set_record(False)
            return

        if check_first_record(self.public_data.product.id):
            self.public_data.has_start_record = True

        self.public_data.data_save_signal = True
        self.set_record(True)

    def add_bend_data_to_chart(self):
        """将新增的数据添加到折线图中"""
        bend_dict = self.public_data.bend_data_dict
        self.bend_value_count += 1
        a_bend = bend_dict["A"]
        b_bend = bend_dict["B"]
        t_bend = bend_dict["T"]
        a_acc = bend_dict["A_ACC"]
        b_acc = bend_dict["B_ACC"]
        # print("Chart_A添加的数据：",self.bend_value_count,a_bend)
        print("Chart_BENT添加的数据：", self.bend_value_count, t_bend)
        # self.ser_bend_chart_A.append(self.bend_value_count, a_bend)
        # self.ser_bend_chart_B.append(self.bend_value_count, b_bend)
        self.ser_bend_chart_All.append(self.bend_value_count, t_bend)
        # self.ser_acc_chart_A.append(self.bend_value_count, a_acc)
        # self.ser_acc_chart_B.append(self.bend_value_count, b_acc)
        self.get_x_range()

    def get_x_range(self):
        count = self.bend_value_count
        if count / self.range_number > 0.9:
            self.range_number = self.range_number * 2
            self.axis_x.setRange(0, self.range_number)
            self.ser_bend_chart_Alarm.append(self.range_number, self.public_data.agree_max)

    def test_chart(self):
        while True:
            sleep(0.5)
            self.bend_value_count += 1
            # 生成一个10-30的随机数
            random_num = random.randint(10, 30)
            self.ser_bend_chart_All.append(self.bend_value_count, random_num)
            print("Chart_BENT添加的数据：", self.bend_value_count, random_num)
            # self.ser_bend_chart_Alarm.append(self.bend_value_count,self.agree_max)
            self.get_x_range()
